package com.rockzhai.ai;


import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.image.BufferedImage;
import java.lang.Exception;
import java.lang.Math;
import java.lang.SecurityException;
import java.lang.String;
import java.lang.System;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.Timer;
import javax.swing.event.MouseInputListener;

//本人Gitee主页：https://gitee.com/mimocvb
public final class DrawingPanel implements ActionListener, MouseMotionListener,  WindowListener {   
    // 常量
    public static final String HEADLESS_PROPERTY   = "my.headless";
    public static final String MULTIPLE_PROPERTY   = "my.multiple";
    public static final String SAVE_PROPERTY       = "my.save";
    private static final String TITLE              = "AI先手对弈";
    private static final int DELAY                 = 100;     // 延时delay between repaints in millis
    private static final int MAX_SIZE              = 10000;   // max width/height
    private static final boolean DEBUG             = false; 	  // DeBug 开关
    private static int instances = 0;
    private static Thread shutdownThread = null;
    static ImagePanel g3;                 // 2D绘图 graphics context 的对象
    
    //预选框参数定义
    static int ax = 0;
    static int ay = 0;
    
    private static Image image1_1 = (Image) new ImageIcon("file/A_background.jpg").getImage();
    private static Image image1_2 = (Image) new ImageIcon("file/B_background.jpg").getImage();
    private static Image image1_3 = (Image) new ImageIcon("file/C_background.jpg").getImage();
    private static Image image_mouse = (Image) new ImageIcon("file/mouse_zy.png").getImage();
    
    private static int back_style = 2; //定义皮肤参数
    
    Font f = new Font("微软雅黑",Font.BOLD,13);
    
    private static boolean hasProperty(String name) {
        try {
            return System.getProperty(name) != null;
        } catch (SecurityException e) {
        	// 读值异常，Debug调试时使用
            if (DEBUG) System.out.println("Security exception when trying to read " + name);
            return false;
        }
    }
    
    // 返回主线程是否在运行 main is active
    private static boolean mainIsActive() {
        ThreadGroup group = Thread.currentThread().getThreadGroup();
        int activeCount = group.activeCount();
        
        // 在线程组中寻找主线程
        Thread[] threads = new Thread[activeCount];
        group.enumerate(threads);
        for (int i = 0; i < threads.length; i++) {
            Thread thread = threads[i];
            String name = ("" + thread.getName()).toLowerCase();
            if (name.indexOf("main") >= 0 || 
                name.indexOf("testrunner-assignmentrunner") >= 0) {
                // 找到主线程
                // (TestRunnerApplet's main runner also counts as "main" thread)
                return thread.isAlive();
            }
        }
        
        // 没有找到主线程
        return false;
    }
    
    // 自定义一个ImagePanel
    public static class ImagePanel extends JPanel {
        private static final long serialVersionUID = 0;
        private Image image;
        
        public ImagePanel(Image image) {
            setImage(image);
            setBackground(Color.WHITE);
            setPreferredSize(new Dimension(image.getWidth(this)+10, image.getHeight(this)+10));
            setAlignmentX(0.0f);
        }
        
        public void backg(){
        	
        	switch(back_style){
        	case 1:back_style = 2;break;
        	case 2:back_style = 3;break;
        	case 3:back_style = 1;break;
        	}
        	 panel.repaint();
        	
        }
        
        public void paintComponent(Graphics g) {
        	
            super.paintComponent(g);
            
            Graphics2D g2 = (Graphics2D) g;
            g3 = this;
            //设置背景图皮肤
            switch(back_style){
            case 1:
            	g.drawImage(image1_1, 0, 0, this.getWidth(), this.getHeight(), this);
            	break;
            case 2:
            	g.drawImage(image1_2, 0, 0, this.getWidth(), this.getHeight(), this);
            	break;
            case 3:
            	g.drawImage(image1_3, 0, 0, this.getWidth(), this.getHeight(), this);
            	break;
            }
           
            //绘制预选框
			if(ax > 25 && ay > 25 && ax < 700 && ay < 700 && Ai.isBlack==false) g.drawImage(image_mouse, ax-12, ay-12, 35, 35, this);
			
            g2.drawImage(image, 0, 0, this);
            setOpaque(false);
        }
        
        public void setImage(Image image) {
            this.image = image;
            repaint();
        }
    }

    // 控件
    private int width, height;             // 窗口 frame 的大小
    private static JFrame frame;                  // 总窗口的 frame
    private static JPanel panel;                  // 总的画布面板
    private ImagePanel imagePanel;         // 真正的绘画面板
    private BufferedImage image;           // 记录绘图的情况
    private Graphics2D g2;                 // 2D绘图 graphics context
    private Timer timer;                   // 绘制的动画时间
    private boolean PRETTY = true;         // 消除锯齿操作true to anti-alias
    private int initialPixel;              // 初始化每个像素点
    private JButton restartbutton;
    private JButton exitbutton;
    private JButton stylebutton;
    private JPanel downBar;
    private static JLabel AIstartus;
    
    // 是否显示窗体
    public static void xianshi(){
    	
    	if(frame.isVisible() == true) {
    		String s=String.format("请勿多开");
    		JOptionPane.showMessageDialog(null, s);
    		
    	}
    	else{
    		
        	//鼠标样式
        	Toolkit kit=Toolkit.getDefaultToolkit();
        	Image img=kit.getImage("file/mouse.png");
        	Cursor mouse=kit.createCustomCursor(img, new Point(1,1), "stick");
        	frame.setCursor(mouse);
    		frame.setVisible(true);
    	}
    	
    }
    
    //AI运行状态提示
    public static void AIus(String txt){
		
    	AIstartus.setText(txt);
    	
    }
    
    public DrawingPanel(int width, int height) {
        
    	if (width < 0 || width > MAX_SIZE || height < 0 || height > MAX_SIZE) {
            throw new IllegalArgumentException("Illegal width/height: " + width + " x " + height);
        }
        //synchronized保证在同一时刻最多只有一个线程执行该段代码       
        synchronized (getClass()) {
            instances++;
            if (shutdownThread == null) {
                shutdownThread = new Thread(new Runnable() {
                    public void run() {
                        try {
                            while (true) {
                                //完成执行主线程已经挂掉
                                if ((instances == 0 || shouldSave()) && !mainIsActive()) {
                                    try {
                                       
                                    	frame.dispose();
                                        
                                    } catch (SecurityException sex) {}
                                }

                                Thread.sleep(250);
                            }
                        } catch (Exception e) {}
                    }
                });
                shutdownThread.setPriority(Thread.MIN_PRIORITY);
                shutdownThread.start();
            }
        }
        this.width = width;
        this.height = height;
        
        //if (DEBUG) System.out.println("w=" + width + ",h=" + height +  ",graph=" + isGraphical() + ",save=" + shouldSave());
        
        if (shouldSave()) {
        	
            // 图像不能超过256中颜色
            image = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_INDEXED);
            
            // 用初始化的背景色填充frame，因为它不会透明显示ARGB图像
            Graphics g = image.getGraphics();
            
            // 加上1，防止width或height为0
            g.fillRect(0, 0, width + 1, height + 1);
            
        } else {
        	
        	//ARGB
            image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
            
        }
        initialPixel = image.getRGB(0, 0);        
        g2 = (Graphics2D) image.getGraphics();
        g2.setColor(Color.BLACK);
        
        //抗锯齿
        if (PRETTY) {
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        }
          

        if (isGraphical()) {
           
        	//设置窗体风格，更加好看圆润
        	try {
                for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                    if ("Nimbus".equals(info.getName())) {
                        javax.swing.UIManager.setLookAndFeel(info.getClassName());
                        break;
                    }
                }
            }catch(Exception e) {
            	System.out.println(e);
            }
        	
            panel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
            panel.setPreferredSize(new Dimension(width, height));
            imagePanel = new ImagePanel(image);
            panel.add(imagePanel);

            // 主界面窗格
            frame = new JFrame(TITLE);
            frame.addWindowListener(this);
            JScrollPane center = new JScrollPane(panel);
            frame.getContentPane().add(center);

            AIstartus=new JLabel();
            AIstartus.setFont(f);
            
            //重新开始
            downBar = new JPanel();
            
            ColorAction lis = new ColorAction();
            restartbutton = new JButton("重新开始");
            stylebutton = new JButton("换肤");
            exitbutton = new JButton("退出");
            restartbutton.addActionListener(lis);
            stylebutton.addActionListener(lis);
            exitbutton.addActionListener(lis);
            
            exitbutton.setFont(f);
            stylebutton.setFont(f);
            restartbutton.setFont(f);

            downBar.setLayout(new FlowLayout(FlowLayout.LEFT));
    		downBar.add(restartbutton);
    		downBar.add(stylebutton);
    		downBar.add(exitbutton);
    		downBar.add(AIstartus);
            
    		frame.add(downBar, BorderLayout.SOUTH);
    		
    		frame.setIconImage(new ImageIcon("file/icon.png").getImage());
            
            frame.pack();
            center(frame);
            frame.setVisible(false);
       
            // 重绘update
            timer = new Timer(DELAY, this);
            timer.start();
            
    		//设置禁止调整窗口大小
            frame.setResizable(false); 
            
            frame.setDefaultCloseOperation( JFrame.DO_NOTHING_ON_CLOSE );

        }
    }
    
    //按钮监听事件
    private class ColorAction implements ActionListener{  
          
        @Override
		public void actionPerformed(ActionEvent e) {
        	
			// TODO Auto-generated method stub
			Object obj = e.getSource();
			if (obj == restartbutton)
			{
				System.out.println("重新开始...");
				Ai.initChessBoard(); 
			}
			else if (obj == exitbutton)
			{
				frame.dispose();
				Ai.initChessBoard(); 
			}
			else if (obj == stylebutton){
				
				ImagePanel a = new ImagePanel(image);
				Ai b = new Ai();
				b.style();
				a.backg();
				Ai.initChessBoard(); 
				
			}
        }
    }  

    
    //初始化UI组件
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() instanceof Timer) {
            // 重绘
            panel.repaint();
        }
    }
    
    //添加一系列鼠标键盘监听事件
    public void addKeyListener(KeyListener listener) {
        frame.addKeyListener(listener);
    }
    
    public void addMouseListener(MouseListener listener) {
        panel.addMouseListener(listener);
    }
    
    public void addMouseListener(MouseMotionListener listener) {
        panel.addMouseMotionListener(listener);
    }
    
    public void addMouseMotionListener(MyMouseEvent myMouseEvent) {
        panel.addMouseMotionListener(this);
    }
    
    public void addMouseListener(MouseInputListener listener) {
        panel.addMouseListener(listener);
        panel.addMouseMotionListener(listener);
    }
    
    // 清除所有的线/颜色
    public void clear() {
    	
    	
    	int[] pixels = new int[width * height];
        for (int i = 0; i < pixels.length; i++) {
            pixels[i] = initialPixel;
        }
        image.setRGB(0, 0, width, height, pixels, 0, 1);
        
    }

    // 获得Graphics2D对象
    public Graphics2D getGraphics() {
        return g2;
    }
    
    // 返回Width
    public int getWidth() {
        return width;
    }
    
	public static int round2(int x){            // 得到鼠标点击点附近的棋盘精准点 
        return (x%45<22)?x/45*45:x/45*45+45;  
    }
    

    public void mouseDragged(MouseEvent e) {
    	
    }
    
    // 监听鼠标行为并绘制实时预选框
    public void mouseMoved(MouseEvent e) {

    	ax = round2(e.getX());
		ay = round2(e.getY());	
		panel.repaint();
    	
    }
   
    // frame可见不可见
    public void setVisible(boolean visible) {
        if (isGraphical()) {
            frame.setVisible(visible);
        }
    }
    
    // 关闭，退出
    public void windowClosing(WindowEvent event) {
    	
    	frame.dispose();
        Ai.initChessBoard();
    }
    
    // 实现WindowListener必须的方法
    public void windowActivated(WindowEvent event) {}
    public void windowClosed(WindowEvent event) {}
    public void windowDeactivated(WindowEvent event) {}
    public void windowDeiconified(WindowEvent event) {}
    public void windowIconified(WindowEvent event) {}
    public void windowOpened(WindowEvent event) {}
   
    // 把主窗口放到屏幕中间
    private void center(Window frame) {
        Toolkit tk = Toolkit.getDefaultToolkit();
        Dimension screen = tk.getScreenSize();
        
        int x = Math.max(0, (screen.width - frame.getWidth()) / 2);
        int y = Math.max(0, (screen.height - frame.getHeight()) / 2);
        frame.setLocation(x, y);
    }   

    private boolean isGraphical() {
        return !hasProperty(SAVE_PROPERTY) && !hasProperty(HEADLESS_PROPERTY);
    }
     
    private boolean shouldSave() {
        return hasProperty(SAVE_PROPERTY);
    }

}

